import axios, { AxiosError, InternalAxiosRequestConfig } from 'axios';
import type { AxiosResponse } from 'axios';
import { Message } from '@arco-design/web-vue';
import { getToken } from '@/utils/auth';
import { throttle } from 'lodash';

export interface HttpResponse<T = unknown> {
  status: number;
  msg: string;
  code: string;
  data: T;
}

if (import.meta.env.VITE_API_BASE_URL) {
  axios.defaults.baseURL = import.meta.env.VITE_API_BASE_URL;
}

axios.interceptors.request.use(
  (config: InternalAxiosRequestConfig<any>) => {
    // let each request carry token
    // this example using the JWT token
    // Authorization is a custom headers key
    // please modify it according to the actual situation
    const token = getToken();
    if (token) {
      if (!config.headers) {
        // @ts-ignore
        config.headers = {};
      }
      config.headers.Authorization = token;
    }
    return config;
  },
  (error) => {
    // do something
    return Promise.reject(error);
  }
);

/**
 * 节流控制，防止重复请求
 */
const throttledError = throttle((error: string) => Message.error(error), 3000, {
  trailing: false,
});

// add response interceptors
axios.interceptors.response.use(
  (response: AxiosResponse<any, any>) => {
    const res = response.data;
    // 0成功，1失败
    // 全局统一拦截展示失败原因,不用每个请求单独写
    if (res.code !== '1') {
      Message.error({
        content: res.msg || '不明原因的错误',
        duration: 5 * 1000,
      });
      return Promise.reject(new Error(res.msg || 'Error'));
    }
    return res.data;
  },
  (error) => {
    /**
     * 非axios的异常不处理
     */
    if (!(error instanceof AxiosError)) throw error;

    const status = error.response?.status;
    /**
     * 异常码 401
     * 验证失效
     * 登出
     */
    if (status === 401) {
      // 异常需要忽略掉
      throw new Error('401 权限不足了，重新登录！！！');
    }

    if (status === 403) {
      throttledError(error.response?.data?.msg ?? '');
      throw new Error('403 接口权限不足');
    }

    /**
     * 500以上服务器异常
     */
    if (status && status >= 500) {
      throttledError('服务器异常');
      throw error;
    }

    if (status === 404) {
      throttledError('请求资源不存在');
      throw error;
    }

    // 400错误码也是提示
    if (status === 400) {
      throttledError(error.response?.data?.msg ?? '');
    }

    return Promise.reject(error);
  }
);
